import { RTC_CONFIGURATION, MEDIA_CONSTRAINTS } from '@/utils/constants';
import { ConnectionState, CallStats } from '@/types';

/**
 * WebRTC 连接管理类
 */
export class WebRTCManager {
  private peerConnection: RTCPeerConnection | null = null;
  private localStream: MediaStream | null = null;
  private remoteStream: MediaStream | null = null;
  private isInitiator = false;
  private connectionState: ConnectionState = {
    isConnected: false,
    connectionState: 'new',
    iceConnectionState: 'new',
  };

  // 事件回调
  private onLocalStreamCallback?: (stream: MediaStream) => void;
  private onRemoteStreamCallback?: (stream: MediaStream) => void;
  private onConnectionStateChangeCallback?: (state: ConnectionState) => void;
  private onIceCandidateCallback?: (candidate: RTCIceCandidate) => void;
  private onDataChannelCallback?: (channel: RTCDataChannel) => void;

  constructor() {
    this.initializePeerConnection();
  }

  /**
   * 初始化 RTCPeerConnection
   */
  private initializePeerConnection(): void {
    try {
      this.peerConnection = new RTCPeerConnection(RTC_CONFIGURATION);
      this.setupPeerConnectionEvents();
    } catch (error) {
      console.error('初始化 RTCPeerConnection 失败:', error);
      throw new Error('WebRTC 不支持或初始化失败');
    }
  }

  /**
   * 设置 PeerConnection 事件监听
   */
  private setupPeerConnectionEvents(): void {
    if (!this.peerConnection) return;

    // ICE 候选者事件
    this.peerConnection.onicecandidate = (event) => {
      if (event.candidate && this.onIceCandidateCallback) {
        this.onIceCandidateCallback(event.candidate);
      }
    };

    // 远程流事件
    this.peerConnection.ontrack = (event) => {
      console.log('接收到远程流:', event.streams[0]);
      this.remoteStream = event.streams[0];
      if (this.onRemoteStreamCallback) {
        this.onRemoteStreamCallback(this.remoteStream);
      }
    };

    // 连接状态变化
    this.peerConnection.onconnectionstatechange = () => {
      if (this.peerConnection) {
        this.connectionState = {
          isConnected: this.peerConnection.connectionState === 'connected',
          connectionState: this.peerConnection.connectionState,
          iceConnectionState: this.peerConnection.iceConnectionState,
        };
        
        console.log('连接状态变化:', this.connectionState);
        
        if (this.onConnectionStateChangeCallback) {
          this.onConnectionStateChangeCallback(this.connectionState);
        }
      }
    };

    // ICE 连接状态变化
    this.peerConnection.oniceconnectionstatechange = () => {
      if (this.peerConnection) {
        console.log('ICE 连接状态:', this.peerConnection.iceConnectionState);
        this.connectionState.iceConnectionState = this.peerConnection.iceConnectionState;
        
        if (this.onConnectionStateChangeCallback) {
          this.onConnectionStateChangeCallback(this.connectionState);
        }
      }
    };

    // 数据通道事件
    this.peerConnection.ondatachannel = (event) => {
      const channel = event.channel;
      console.log('接收到数据通道:', channel.label);
      
      if (this.onDataChannelCallback) {
        this.onDataChannelCallback(channel);
      }
    };
  }

  /**
   * 获取用户媒体设备
   */
  async getUserMedia(constraints: MediaStreamConstraints = MEDIA_CONSTRAINTS): Promise<MediaStream> {
    try {
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      this.localStream = stream;
      
      // 添加本地流到 PeerConnection
      if (this.peerConnection) {
        stream.getTracks().forEach(track => {
          this.peerConnection!.addTrack(track, stream);
        });
      }
      
      console.log('获取本地媒体流成功:', stream);
      
      if (this.onLocalStreamCallback) {
        this.onLocalStreamCallback(stream);
      }
      
      return stream;
    } catch (error) {
      console.error('获取媒体设备失败:', error);
      throw error;
    }
  }

  /**
   * 创建 Offer
   */
  async createOffer(): Promise<RTCSessionDescriptionInit> {
    if (!this.peerConnection) {
      throw new Error('PeerConnection 未初始化');
    }

    try {
      this.isInitiator = true;
      const offer = await this.peerConnection.createOffer({
        offerToReceiveAudio: true,
        offerToReceiveVideo: true,
      });
      
      await this.peerConnection.setLocalDescription(offer);
      console.log('创建 Offer 成功:', offer);
      
      return offer;
    } catch (error) {
      console.error('创建 Offer 失败:', error);
      throw error;
    }
  }

  /**
   * 创建 Answer
   */
  async createAnswer(offer: RTCSessionDescriptionInit): Promise<RTCSessionDescriptionInit> {
    if (!this.peerConnection) {
      throw new Error('PeerConnection 未初始化');
    }

    try {
      await this.peerConnection.setRemoteDescription(offer);
      
      const answer = await this.peerConnection.createAnswer();
      await this.peerConnection.setLocalDescription(answer);
      
      console.log('创建 Answer 成功:', answer);
      
      return answer;
    } catch (error) {
      console.error('创建 Answer 失败:', error);
      throw error;
    }
  }

  /**
   * 设置远程 Answer
   */
  async setRemoteAnswer(answer: RTCSessionDescriptionInit): Promise<void> {
    if (!this.peerConnection) {
      throw new Error('PeerConnection 未初始化');
    }

    try {
      await this.peerConnection.setRemoteDescription(answer);
      console.log('设置远程 Answer 成功');
    } catch (error) {
      console.error('设置远程 Answer 失败:', error);
      throw error;
    }
  }

  /**
   * 添加 ICE 候选者
   */
  async addIceCandidate(candidate: RTCIceCandidateInit): Promise<void> {
    if (!this.peerConnection) {
      throw new Error('PeerConnection 未初始化');
    }

    try {
      await this.peerConnection.addIceCandidate(candidate);
      console.log('添加 ICE 候选者成功:', candidate);
    } catch (error) {
      console.error('添加 ICE 候选者失败:', error);
      throw error;
    }
  }

  /**
   * 切换音频状态
   */
  toggleAudio(): boolean {
    if (!this.localStream) return false;
    
    const audioTrack = this.localStream.getAudioTracks()[0];
    if (audioTrack) {
      audioTrack.enabled = !audioTrack.enabled;
      console.log('音频状态:', audioTrack.enabled ? '开启' : '关闭');
      return audioTrack.enabled;
    }
    return false;
  }

  /**
   * 切换视频状态
   */
  toggleVideo(): boolean {
    if (!this.localStream) return false;
    
    const videoTrack = this.localStream.getVideoTracks()[0];
    if (videoTrack) {
      videoTrack.enabled = !videoTrack.enabled;
      console.log('视频状态:', videoTrack.enabled ? '开启' : '关闭');
      return videoTrack.enabled;
    }
    return false;
  }

  /**
   * 获取音频状态
   */
  isAudioEnabled(): boolean {
    if (!this.localStream) return false;
    const audioTrack = this.localStream.getAudioTracks()[0];
    return audioTrack ? audioTrack.enabled : false;
  }

  /**
   * 获取视频状态
   */
  isVideoEnabled(): boolean {
    if (!this.localStream) return false;
    const videoTrack = this.localStream.getVideoTracks()[0];
    return videoTrack ? videoTrack.enabled : false;
  }

  /**
   * 获取连接统计信息
   */
  async getStats(): Promise<CallStats | null> {
    if (!this.peerConnection) return null;

    try {
      const stats = await this.peerConnection.getStats();
      let packetsLost = 0;
      let bytesReceived = 0;
      let bytesSent = 0;
      let frameRate = 0;
      let resolution = { width: 0, height: 0 };

      stats.forEach((report) => {
        if (report.type === 'inbound-rtp' && report.kind === 'video') {
          packetsLost += report.packetsLost || 0;
          bytesReceived += report.bytesReceived || 0;
          frameRate = report.framesPerSecond || 0;
        }
        
        if (report.type === 'outbound-rtp' && report.kind === 'video') {
          bytesSent += report.bytesSent || 0;
        }
        
        if (report.type === 'track' && report.kind === 'video') {
          resolution.width = report.frameWidth || 0;
          resolution.height = report.frameHeight || 0;
        }
      });

      return {
        duration: 0, // 需要外部计算
        packetsLost,
        bytesReceived,
        bytesSent,
        frameRate,
        resolution,
      };
    } catch (error) {
      console.error('获取统计信息失败:', error);
      return null;
    }
  }

  /**
   * 关闭连接
   */
  close(): void {
    // 停止本地流
    if (this.localStream) {
      this.localStream.getTracks().forEach(track => track.stop());
      this.localStream = null;
    }

    // 关闭 PeerConnection
    if (this.peerConnection) {
      this.peerConnection.close();
      this.peerConnection = null;
    }

    this.remoteStream = null;
    this.connectionState = {
      isConnected: false,
      connectionState: 'closed',
      iceConnectionState: 'closed',
    };

    console.log('WebRTC 连接已关闭');
  }

  // Getter 方法
  getLocalStream(): MediaStream | null {
    return this.localStream;
  }

  getRemoteStream(): MediaStream | null {
    return this.remoteStream;
  }

  getConnectionState(): ConnectionState {
    return this.connectionState;
  }

  isConnected(): boolean {
    return this.connectionState.isConnected;
  }

  // 事件回调设置
  onLocalStream(callback: (stream: MediaStream) => void): void {
    this.onLocalStreamCallback = callback;
  }

  onRemoteStream(callback: (stream: MediaStream) => void): void {
    this.onRemoteStreamCallback = callback;
  }

  onConnectionStateChange(callback: (state: ConnectionState) => void): void {
    this.onConnectionStateChangeCallback = callback;
  }

  onIceCandidate(callback: (candidate: RTCIceCandidate) => void): void {
    this.onIceCandidateCallback = callback;
  }

  onDataChannel(callback: (channel: RTCDataChannel) => void): void {
    this.onDataChannelCallback = callback;
  }
}

// 导出默认实例
export default WebRTCManager;